package com.societyGames.codeAlong.codeExercise
{
import com.societyGames.system.EventObject;

import flash.display.Loader;
import flash.events.Event;
import flash.events.EventDispatcher;
import flash.system.ApplicationDomain;
import flash.system.LoaderContext;
import flash.utils.ByteArray;

public class Executor extends EventDispatcher
{
  private var _completeEventObject:EventObject; //Event. When code has completed executing.
  private var _isExecuting:Boolean = false;
  private var _swfApplicationDomain:ApplicationDomain;
  private var _loader:Loader;

  public function Executor()
  {
    this._completeEventObject = new EventObject(this, Event.COMPLETE);
  }

  public function get completeEventObject():EventObject //Event
  {
    return this._completeEventObject;
  }

  public function execute(swfByteArray:ByteArray, parentApplicationDomain:ApplicationDomain = null):void
  {
    if (this._isExecuting)
    {
      throw new Error("Cannot call execute() while already executing.");
    }

    this._isExecuting = true;
    this._swfApplicationDomain = new ApplicationDomain(parentApplicationDomain);
    var loaderContext:LoaderContext = new LoaderContext(false, this._swfApplicationDomain, null);
    loaderContext.allowCodeImport = true; //For editor.

    this._loader = new Loader();
    this._loader.contentLoaderInfo.addEventListener(Event.INIT, swfInitHandler);
    this._loader.contentLoaderInfo.addEventListener(Event.COMPLETE, swfCompleteHandler);
    this._loader.loadBytes(swfByteArray, loaderContext);
  }

  private function swfCompleteHandler(event:Event):void
  {
  }

  private function swfInitHandler(event:Event):void
  {
    cleanUp();
    this._completeEventObject.dispatchEvent();
  }

  private function cleanUp():void
  {
    this._swfApplicationDomain = null;
    if (this._loader != null)
    {
      this._loader.contentLoaderInfo.addEventListener(Event.INIT, swfInitHandler);
      this._loader.contentLoaderInfo.removeEventListener(Event.COMPLETE, swfCompleteHandler);
      this._loader.unloadAndStop(true);
      this._loader = null;
    }
    this._isExecuting = false;
  }
}
}